/* ==================================================================
* Copyright (c) 2024/12/06 SCNU LiuJunJie z-ken
* All rights reserved.
* fileName:	mainwindow.h
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the xxx Group. and
* its contributors.
* 4. Neither the name of the Group nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Author,GROUP AND CONTRIBUTORS
* ===================================================================
* Author: LiuJunJie z-ken.
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QPushButton>
#include<QPlainTextEdit>
#include<QMessageBox>
#include<QTextStream>
#include<QDialog>
#include<QFileDialog>
#include<QDebug>
#include<QTabWidget>
#include<QTableWidget>
#include<QProgressDialog>
#include<QThread>
#include<QTreeWidget>
#include<QComboBox>
#include"dialogutil.h"
#include"reworker.h"
#include <QtConcurrent/QtConcurrent>
#include"waitdialog.h"
#include"lalrworker.h"
#include "./partRe/reToDfaAlgor.h"
#include"./partLalr/myalgor.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    // 将ui中的指针一一赋值
    void assignUiPoint();

    // re中的按钮绑定事件的执行函数
    void reItemBuild();

    // 生成NFA和DFA的表格展示窗口
    void GenerateReNfaDfaAndShow();

    // 生成完成后显示源代码窗口
    void buildJointFileSourceCodeEdit();

    // 构建tableWidgit
    void buildReDfaTableWidgit();
    // 设置NFA表格
    void setNFA(QTableWidget * tableWidgit, const NfaRecord& nfaRecord);
    // 设置DFA表格
    void setDFA(QTableWidget * tableWidgit, const DfaRecord& dfaRecord);


private:
    // tabWidgetRe中ui的指针
    ReToDfaAlgor reToDfaAlgor;
    QPlainTextEdit* rePlaintextEdit;
    QPlainTextEdit* reGenerateCodeTextEdit; // 生成代码的文本Edit
    QPushButton * openReFile;// 打开正则文件按钮
    QString reFilePath="";    // 正则的文件路径
    QPushButton * reSaveFile;// 保存正则文件按钮
    QPushButton *  reGenerate; // 生成代码按钮
    QPushButton *  reSelectOutputSourceCodePosBtn; // 选择分析器源代码生成位置按钮
    QString reOutputSourceCodePath=""; // 输出源代码文件的路径


    QPushButton *  reCreateFile; // 创建文件按钮
    QTabWidget * tabWidgitReNFA;
    QTabWidget * tabWidgitReDFA;
    QTabWidget * tabWidgitReMinDFA;

    void connectEventRe_Tab_1();



    // re中第二个Tab栏相关的按钮
    QPushButton *  reOpenSelectSourceFileCodeBtn;// 打开需要编码的文件按钮
    QString reSelectedSourceCodePath=""; // 选择源代码的路径
    QPushButton * reCompileSourceCodeBtn;// 执行编译，编译选择的代码按钮

    QPushButton * reSelectOutputExePathBtn;// 编码文件输出位置获取按钮
    QString reOutPutJointExePath="";// 输出可执行文件的位置
    QPushButton * reGenerateTokenTypeBtn ;// 执行代码，生成编码文件按钮
    QPushButton * reSelectOrignFileBtn;// 选择需要被分析的文件
    QString reAnalysedOrignFilePath=""; //需要分析器分析文件的位置
    QPushButton *  reEncodingFilePathBtn;//选择文件被分析后的分析结果位置
    QString reEncodingFilePath="";

    QPushButton *  saveAnalyedFileChangeBtn; // 保存对分析文件的修改按钮
    QPushButton *  saveEncodedFileChangeBtn; // 保存对编码文件的修改按钮

    QPlainTextEdit* reUserSelectGenerateCodeTextEdit; // 用户打开的文本文件
    QPlainTextEdit*  reEncodingFileContentEdit; // 打开的编码文件显示的Edit
    QPlainTextEdit*   reAnalyzedOriginFileEdit;
    void connectEventRe_Tab_2();


    // codec读取文件解码器，支持utf-8编码
    QTextCodec *codec = QTextCodec::codecForName("utf-8");

private: // LALR相关的遍历内容
    // 处理attributeNameBox的名字，对算法对象进行配置
    void processAttributeNameBox();
    QString lalrAttrbuteFilePath;

    // lalr中第一个tab的指针和内容
    QPushButton *lalrOpenFile; // lalr打开文件
    QString productionFilePath;
    QPushButton *lalrGenerate; // lalr生成DFA和分析表
    QPushButton *lalrSaveFile;  // lalr保存文法文件
    QPlainTextEdit * lalrProductionTextEdit; //lalr 的文法编辑窗口

    QTableWidget* productionsTable; // lalr的文法展示table
    QTableWidget * firstSetTable;  // 文法的first集合
    QTableWidget * followSetTable;
    QTableWidget * LR_DFA_Table; // LR的DFA表格
    QTreeWidget * LR_DFA_item_Table; // LR的树节点结构展示
    QTableWidget * LALR_DFA_Table; // LALR的DFA表格
    QTreeWidget * LALR_DFA_item_WidgetTable; // LALR的树节点结构展示
    QTableWidget *  analyseSheetTable; // 分析表的展示

    ParseAlgor lalrAlgor;// 算法核心

    void connectEventLalr_Tab_1();

    // 进行生成和渲染数据
    void generateLalrAndShow();
    // 生成分析表，其中会进行最小化 -- 弃用
    //    void generateLalrDfaAndAnalyseSheet();
    // 进行数据的渲染
    void buildLalrDfaTableWidgitAndSheet();


    // 一个一个表格进行渲染
    void productionsTableSetUp();
    void firstSetTableSetUp();
    void followSetTableSetUp();
    void LR_DFA_TableSetUp();
    void LALR_DFA_TableSetUp();
    void analyseSheetTableSetUp();

    // lalr的Tab2
    // lalr中第二个tab的指针和内容
    QPlainTextEdit* lalrEncodedFileTextEdit; // 编码文件展示框
    QString lalrEncodedFilePath;
    QPlainTextEdit* lalrJointFileSourceCodeEdit; // 分析器源代码文本框
    QString lalrJointFileSourceCodePath;
    QPlainTextEdit* lalrOriginFileEdit ; // 未编码文件文本框
    QString lalrOriginFilePath;
    QPushButton* lalrOpenEncodedFileBtn; // 打开编码文件
    QPushButton* lalrOpenJointFileBtn; // 打开分析器文件
    QPushButton* lalrOpenOriginFileBtn; // 打开未编码文件

    QPushButton* lalrProcessByEncodedFileBtn; // 使用编码文件执行分析
    QPushButton* lalrProcessByJointFileAndOriginFileBtn; // 使用分析器和未编码文件进行分析

    void connectEventLalr_Tab_2();

    QComboBox *atrributeNameBox; // 复选框
    QTableWidget* lalrAnalyseRecordTableWidget;
    QTreeWidget* lalrAstTreeWidget;
    QTreeWidget* lalrAnalyseTreeWidget;
    // 批量构建分析记录、语法树、分析树
    void buildAnalyseRecord_Ast_AnalyseTree();

    void buildAnalyseRecord();
    void buildAst();
    void buildAnalyseTree();
    void buildFac();
    void buildAformatStTree();


    // 构建语法树节点
    QTreeWidgetItem* buildAstTreeNodes();
    // 构建语法树节点的辅助函数
    QTreeWidgetItem* buildAstTreeNodesSupport(QTreeWidgetItem *root,AstTreeNode *astRoot, int depth);

    // 构建分析树
    QTreeWidgetItem*  buildAnalyseTreeNodes() ;
    // 构建分析树节点辅助函数
    QTreeWidgetItem* buildAnalyseTreeNodesSupport(QTreeWidgetItem *root,int rootId, int depth);
    // 构建第二个语法树节点
    QTreeWidgetItem* buildAformatStTreeNodes();
    // 辅助函数
    QTreeWidgetItem* buildAformatStTreeNodesSupport(QTreeWidgetItem *root,AstTreeNode *astRoot, int depth);





private:
    Ui::MainWindow *ui;

signals:
    void finished();  // 任务完成信号
    void finished_lalr();
};
#endif // MAINWINDOW_H
